package com.xiaobias.utils;

import com.xiaobias.controller.JavaToaSmaliController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.HashMap;

public class Java2Smali {

    private final static Logger logger = LoggerFactory.getLogger(Java2Smali.class);

//    public static final String absPath = "/Users/lw/IdeaProjects/javaToSmali/";
    public static final String absPath = "/home/javaToSmali/";
    public static final String JAVADIR = absPath + "java";
    public static final String SMALIDIR = absPath + "smali";
    public static final String CLASSDIR = absPath + "classes";
    public static final String lib = absPath + "/lib";

    public static final String sysSeparator = File.separator;

    public static final String JAVA_PATH = JAVADIR + sysSeparator;
    public static final String SMALI_PATH = SMALIDIR + sysSeparator;
    public static final String CLASS_PATH = CLASSDIR + sysSeparator;

    public static final String DEXNAME = SMALI_PATH + "classes.dex";

    static boolean isOutputLog = true;


    public static final HashMap<String, String> classNamePkgMap = new HashMap<String, String>();

    public static void compileJava2Smali() {

        //第一步：编译java文件夹下面所有的java文件
        File javaDirFile = new File(JAVADIR);
        if (!javaDirFile.exists()) {
            javaDirFile.mkdirs();
        }
        File classDirFile = new File(CLASSDIR);
        if (!classDirFile.exists()) {
            classDirFile.mkdirs();
        }

        String javaCmd = "javac -classpath " + lib + "/android.jar " + JAVA_PATH + "*.java";
        boolean isSucc = Utils.execCmd(javaCmd, isOutputLog);
        if (!isSucc) {
            System.out.println("compile java file: is error!");
            return;
        }

        File[] javaFileList = javaDirFile.listFiles();
        assert javaFileList != null;
        for (File javaF : javaFileList) {
            if (javaF.getName().endsWith(".java")) {
                String pkgName = Utils.getClassPkgName(javaF.getAbsolutePath());
                if (pkgName == null) {
                    continue;
                }
                pkgName = pkgName.replace(".", sysSeparator);
                File dir = new File(CLASS_PATH + pkgName);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                classNamePkgMap.put(Utils.getFileName(javaF.getName()), pkgName);
                logger.info("pkgName : " + pkgName);
            }
        }
        for (File classF : javaFileList) {
            if (classF.getName().endsWith(".class")) {
                String pkgName = classNamePkgMap.get(Utils.getFileName(classF.getName()));
                File classFile = new File(JAVA_PATH + classF.getName());
                boolean isCopySucc = Utils.fileCopy(classFile.getAbsolutePath(),
                        CLASS_PATH + pkgName + sysSeparator + classF.getName());
                if (!isCopySucc) {
                    System.out.println("copy class file:" + classF.getName() + " is error!");
                } else {
                    logger.info("delete " + pkgName);
                    classFile.delete();
                }
            }
        }

        //第二步：利用dx命令将class文件变成dex文件
        File smaliDirFile = new File(SMALIDIR);
        if (!smaliDirFile.exists()) {
            smaliDirFile.mkdirs();
        }
        String dxCmd = "java -jar " + lib + "/dx.jar --dex --output=" + DEXNAME + " " + CLASSDIR;
        boolean isdxSucc = Utils.execCmd(dxCmd, isOutputLog);
        if (!isdxSucc) {
            logger.error("class file to classes.dex is error!");
            return;
        }

        //第三步：利用smali将dex文件变成smali文件
        String smaliCmd = "java -jar " + lib + "/baksmali.jar -o " + SMALIDIR + " " + DEXNAME;
        boolean smaliSucc = Utils.execCmd(smaliCmd, isOutputLog);
        if (!smaliSucc) {
            logger.error("dex to smali is error!");
            return;
        } else {
            File classDexFile = new File(DEXNAME);
            if (classDexFile.exists()) {
                classDexFile.delete();
            }
        }

        // 第四步：删除classes目录
        if (classDirFile.exists()) {
            classDirFile.delete();
        }
    }


}
